function loadEpisode(sentencesArray, mediaUrl, realDuration, episodes, currentEpisodeId)
{
    //因为IE、旧版Edge、部分手机内置浏览器(小米等)中对于部分音频,
    //计算的duration以及currentTime和实际的不一致，因此需要根据服务器端
    //计算出来的实际长度，在客户端做按比例校正
    var playerTime2RealTime = function(playerTime)
    {
        var mainPlayer = document.getElementById("mainPlayer");
        var playerDuration = mainPlayer.duration;
        return playerTime * realDuration / playerDuration;
    }

    var realTime2PlayerTime = function(realTime)
    {
        var mainPlayer = document.getElementById("mainPlayer");
        var playerDuration = mainPlayer.duration;
        return realTime * playerDuration / realDuration;
    }

    var app = new Vue({
        el: '#app',
        data:
        {
            filters: [],
            sentences: [],
            showSentense: false,//是否显示原文
            sentenceEnd: Number.MAX_VALUE,//sentencePlayer停止播放的时间,
            currentSentence: { Value: '' },//当前播放的句子,
            isCacheEnabled: false,//当前设备是否支持缓存
            cacheStatus: "",//缓存状态： 'playOffline','downloading','downloaded','playOnline'
            downloadProgress: 0,//缓存下载进度
            cacheMessage: "",//缓存区域提示消息
            mediaUrl: mediaUrl,//音频或者视频的路径
            playbackRate: 1,
            isPlayBackRateSupported: false,//浏览器是否支持变速
        },
        mounted: function ()
        {
            //https://stackoverflow.com/questions/23738213/html5-audio-how-to-check-if-playbackrate-is-supported
            this.isPlayBackRateSupported = ('playbackRate' in document.createElement('audio'));

            Array.prototype.push.apply(this.sentences, sentencesArray);
            this.isCacheEnabled = (typeof (window.webkitRequestFileSystem) != 'undefined')
                && (navigator.userAgent.toLowerCase().indexOf('mobile') > -1);//cache on Desktop browser is useless,
            //but it will make user confused, so we disable cache on Desktop browser
            if (!this.isCacheEnabled)
            {
                var mainPlayer = document.getElementById("mainPlayer");
                mainPlayer.src = this.mediaUrl;
                mainPlayer.play();
            }
            else
            {
                var isCellularNetwork = function ()
                {
                    var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
                    if (typeof (connection) == "undefined")
                    {
                        return null;
                    }
                    return connection.type == "cellular";
                }

                //detect the local cache file
                var localFileName = md5(this.mediaUrl);//use the MD5 value of Url as local file name
                var vueThis = this;
                var playOnline = function ()
                {
                    vueThis.cacheStatus = "playOnline";
                    var mainPlayer = document.getElementById("mainPlayer");
                    if (isCellularNetwork() == true)
                    {
                        weui.toast("Online playing, mind your data usage");
                        mainPlayer.removeAttribute("autoplay");
                    }
                    mainPlayer.src = vueThis.mediaUrl;
                    //mainPlayer.play();
                };

                var tryLocalCacheSuccess = function (fileEntry)
                {
                    fileEntry.getMetadata(function (metaData)
                    {
                        //if previous download was interrupted, the file size may be zere,
                        //so play remote
                        if (metaData.size <= 0)
                        {
                            playOnline();
                        }
                        else if (metaData.size > 0)
                        {
                            vueThis.cacheStatus = "playOffline";
                            weui.toast("Offline playing");
                            var mainPlayer = document.getElementById("mainPlayer");
                            mainPlayer.src = fileEntry.toURL();
                            mainPlayer.play();
                        }
                    });
                };

                var requestFSSuccess = function (fs)
                {
                    fs.root.getFile(localFileName, {}, tryLocalCacheSuccess, playOnline);
                };
                var requestFSFail = function (e)
                {
                    alert("webkitRequestFileSystem Error:" + e);
                };

                window.webkitRequestFileSystem(window.TEMPORARY, 200 * 1024 * 1024, requestFSSuccess, requestFSFail);
            }
        },
        methods:
        {
            chooseEpisode: function () {
                var items = new Array();
                for (var i = 0; i < episodes.length; i++) {
                    var episode = episodes[i];
                    items.push({
                        label: episode.Name,
                        value: episode.Id,
                    });
                }
                weui.picker(items, {
                    defaultValue: [currentEpisodeId],
                    onConfirm: function (result) {
                        var id = result[0].value;//episode id
                        location.href = "/ListeningExercise/Episode/" + id + "/?mediaType=audio";
                    }
                });
            },
            //从【听不懂】列表中删除一条
            removeFromFilters: function (filterToRemove)
            {
                var i = this.filters.indexOf(filterToRemove);
                this.filters.splice(i, 1)
            },
            translateSentence: function (sentence)
            {
                window.closeFanyiDialog = function ()
                {
                    //隐藏对话框和遮罩层
                    document.getElementById("fanyiDialog").style.display = 'none';
                    document.getElementById('shadowFanyiDialog').style.display = 'none';
                };
                //点击遮罩层，也是关闭对话框
                document.getElementById('shadowFanyiDialog').onclick = window.closeFanyiDialog;
                var fanyiUrl = "https://fanyi.baidu.com/?aldtype=38319&tpltype=sigma&sfr_fb=0#en/zh/" + encodeURIComponent(sentence);
                document.getElementById("frameFanYi").src = fanyiUrl;
                document.getElementById("fanyiDialog").style.display = 'block';
                //显示遮罩层
                document.getElementById('shadowFanyiDialog').style.display = "block";
            },
            hidePlaybackRateMenu: function ()
            {
                var androidActionSheet = document.getElementById("actionsheetSwitchPlaybackRate");
                androidActionSheet.style.display = "none";
            },
            showSwitchPlaybackRate: function ()
            {
                //显示ActionSheet菜单
                var androidActionSheet = document.getElementById("actionsheetSwitchPlaybackRate");
                var androidMask = androidActionSheet.getElementsByClassName('weui-mask')[0];
                androidActionSheet.style.display = "block";
                androidMask.onclick = function ()//点击空白区域隐藏菜单
                {
                    app.hidePlaybackRateMenu();
                };
            },
            switchPlaybackRate: function (rate)
            {
                this.hidePlaybackRateMenu();
                this.playbackRate = rate;
                //audio直接绑定playbackRate不行，必须特殊处理https://stackoverflow.com/questions/48388877/vue-js-how-i-can-bind-the-playbackrate-of-a-html5-video-element
                //太麻烦，就手工改dom吧
                var mainPlayer = document.getElementById("mainPlayer");
                mainPlayer.playbackRate = rate;                
            },
            switchSubtitleStatus: function ()
            {
                this.showSentense = !this.showSentense;
                alert('点击原文句子可以翻译哦！');
            },
            //找到包含position这个时间点的句子
            querySentence: function (position)
            {
                if (mediaUrl.indexOf("BeachTV") > 0 && mediaUrl.indexOf("Human") > 0)
                {
                    //var ratio = realDuration / mainPlayer.duration;
                    //position = position * ratio;
                    for (var i = 0; i < this.sentences.length; i++)
                    {
                        var sentence = this.sentences[i];
                        if (position >= sentence.StartTime && position <= sentence.EndTime)
                        {
                            return sentence;
                        }
                    }           
                }
                else
                {
                    //找到包含position这个时间点的句子
                    for (var i = 0; i < this.sentences.length; i++)
                    {
                        var sentence = this.sentences[i];
                        if (position >= sentence.StartTime && position <= sentence.EndTime)
                        {
                            return sentence;
                        }
                    }
                }                
            },
            addToFilter: function () {
                //把听不懂的一句话加入filters
                //加入筛选
                if (this.currentSentence && this.filters.indexOf(this.currentSentence) < 0) {
                    var value = this.currentSentence.Value;
                    value = value.replace(/[^a-zA-Z0-9]+/gi, '');//remove all the non-alphanumeric characters
                    if (value.length > 0)//some transcript is only "..." or empty string,so skip them
                    {
                        this.filters.push(this.currentSentence);
                    }
                }
            },
            //根据当前播放器播放进度更新 this.currentSentence
            updateCurrentSentence: function () {
                var mainPlayer = document.getElementById("mainPlayer");
                    //var position = mainPlayer.currentTime;
                var position = playerTime2RealTime(mainPlayer.currentTime);
                var foundSentence = this.querySentence(position);//查找当前播放的句子
                if (foundSentence && foundSentence !== this.currentSentence)//相同则不更新，提升性能
                {
                    this.currentSentence = foundSentence;//更新当前播放的句子
                }    
            },
            sentencePlayerOnTimeUpdate: function () {
                var mainPlayer = document.getElementById("mainPlayer");
                var position = playerTime2RealTime(mainPlayer.currentTime);
                this.updateCurrentSentence();           
                //播放到一句话到结束 
                if (position && position >= this.sentenceEnd) {
                    mainPlayer.pause();
                    this.sentenceEnd = Number.MAX_VALUE;//片段播放完成就设置为最大值，这样不影响后续播放
                }
            },
            playSentence: function (sentence) {
                //QQ浏览器、安卓浏览器上两个audio一起用有问题，微信没问题。因此改成用一个audio
                //播放筛选出来的一句话
                var mainPlayer = document.getElementById("mainPlayer");
                this.sentenceEnd = sentence.EndTime;//片段停止播放时间点
                //从片段开始播放
                //var ratio = mainPlayer.duration / realDuration;
                //mainPlayer.currentTime = sentence.StartTime * ratio;
                mainPlayer.currentTime = realTime2PlayerTime(sentence.StartTime);
                mainPlayer.play();

                for (var i = 0; i < this.filters.length; i++)
                {
                    var s = this.filters[i];
                }
            },
            clearFilters: function () {
                this.filters.splice(0, this.filters.length);
            },
            goNextSentence: function () {
                this.updateCurrentSentence();//因为在暂停情况下拖动进度条，TimeUpdate事件不会执行
                //因为也就不会根据当前进度更新this.currentSentence
                //这样就会造成在暂停状态下点击【Next】不准确，因此手动更新一下this.currentSentenc
                //跳到下一句（比如当前是一大段的空白）
                
                //找到包含当前时间点的句子的序号
                var currentSentenceIndex = -1;
                if (this.currentSentence) {
                    currentSentenceIndex = this.sentences.indexOf(this.currentSentence);
                }
                //下一句的序号
                var nextSentenceIndex = currentSentenceIndex + 1;
                var nextSentence;
                if (nextSentenceIndex < this.sentences.length)
                {
                    nextSentence = this.sentences[nextSentenceIndex];
                }
                else//如果已经到最后一句，则从头开始
                {
                    nextSentence = this.sentences[0];
                }
                var mainPlayer = document.getElementById("mainPlayer");
                //mainPlayer.currentTime = nextSentence.StartTime;
                mainPlayer.currentTime = realTime2PlayerTime(nextSentence.StartTime);
                mainPlayer.play();
            },
            goPrevSentence: function () {
                //跳到上一句
                var mainPlayer = document.getElementById("mainPlayer");
                //找到包含当前时间点的句子的序号
                var currentSentenceIndex = -1;
                if (this.currentSentence) {
                    currentSentenceIndex = this.sentences.indexOf(this.currentSentence);
                }
                //上一句的序号
                var prevSentenceIndex = currentSentenceIndex - 1;
                if (prevSentenceIndex > 0)
                {
                    var prevSentence = this.sentences[prevSentenceIndex];
                    //mainPlayer.currentTime = prevSentence.StartTime;
                    mainPlayer.currentTime = realTime2PlayerTime(prevSentence.StartTime);
                    mainPlayer.play();
                }
                else
                {
                    weui.toast("这是第一句，没有上一句");
                }
            },
            startCache: function ()
            {
                //1)thanks to: https://imququ.com/post/a-downloader-with-filesystem-api.html
                //2)FileSystem API is only supported on Chrome(Desktop & Mobile).
                //3)File System inspection have been removed from DevTools
                //please install Chrome extention "HTML5 FileSystem Explorer Extended"(https://chrome.google.com/webstore/detail/html5-filesystem-explorer/chkmbbajnboncdmkigkgpjdhppcjhlcc) to manage the File System spaces.
                var vueThis = this;
                this.cacheStatus = "downloading";
                this.cacheMessage = "Preparing for download";
                var downloadOnProgress = function (e)
                {
                    this.cacheStatus = "downloading";
                    var loaded = e.loaded;
                    var totalSize = e.total;
                    var downloadProgress = parseInt(loaded / totalSize * 100);
                    var info = (loaded / (1024 * 1024)).toFixed(2) + 'MB/' + (totalSize / (1024 * 1024)).toFixed(2) + 'MB';
                    vueThis.downloadProgress = downloadProgress;
                    vueThis.cacheMessage = info;
                };

                var localFileName = md5(vueThis.mediaUrl);//use the MD5 value of Url as local file name

                var downloaded = function (downloadInfo)
                {
                    vueThis.cacheStatus = "downloaded";
                    vueThis.downloadProgress = 100;
                   
                    when(createFile(localFileName))
                    .then(function (fileInfo)
                    {
                        fileInfo.fileWriter.onwriteend = function ()
                        {
                            weui.toast("Cache is done");
                            var mainPlayer = document.getElementById("mainPlayer");
                            var prevTime = mainPlayer.currentTime;
                            mainPlayer.src = fileInfo.fileEntry.toURL();
                            mainPlayer.currentTime = prevTime;
                            mainPlayer.play();
                            vueThis.cacheStatus = "playOffline";
                            vueThis.downloadProgress = 100;
                        };
                        fileInfo.fileWriter.write(downloadInfo.blob);                        
                    });
                };
                vueThis.cacheStatus = "downloading";
                vueThis.cacheMessage = 'Preparing';
                var downloader = Downloader(vueThis.mediaUrl, downloadOnProgress);
                when(downloader).then(downloaded).otherwise(function (e) { alert("downloader error"); });
            }
        },
        computed:
        {
            //filtersLength(){} is not supported by IE11,use filtersLength:function(){} instead
            filtersLength: function() {
                return this.filters.length;
            }
        }
    });

    //快捷键，←上一句，→下一句，空格把当前的话加入【听不懂】
    document.onkeydown = function (e)
    {
        e = e || window.event;
        if (e.keyCode == 37)
        {
            app.goPrevSentence();
        }
        else if (e.keyCode == 39)
        {
            app.goNextSentence();
        }
        else if (e.keyCode == 65)//A键
        {
            app.addToFilter();
        }
    }
}

